import { Injectable } from '@nestjs/common';
import { PrismaService } from '@/common/service/prisma/prisma.service';
import { Response } from 'express';
import { exportTable, nowDateTime } from '@/common/utils';
import { v4 as uuidv4 } from 'uuid';
import {
  createOrderDto,
  CreateRentalHouseDto,
  QueryRentalHouseDto,
  UpdateRentalHouseDto,
} from '../dto/index';
import { Prisma } from '@prismaClient';
import { isEmpty, isNotEmpty } from 'class-validator';

@Injectable()
export class RentalHouseService {
  constructor(private prisma: PrismaService) {}

  /** @description 房源购买 */
  async HousePurchase(rentalHouseOrder: createOrderDto, userId: any) {
    // 删除为空的字段
    if (isEmpty(rentalHouseOrder['startDate'])) {
      delete rentalHouseOrder['startDate'];
    }
    if (isEmpty(rentalHouseOrder['endDate'])) {
      delete rentalHouseOrder['endDate'];
    }
    if (isEmpty(rentalHouseOrder['houseId'])) {
      delete rentalHouseOrder['houseId'];
    }
    if (isEmpty(rentalHouseOrder['landlord'])) {
      delete rentalHouseOrder['landlord'];
    }

    // 默认的返回结果
    return await this.prisma
      .$transaction(async (prisma) => {
        const [house, user, landlord] = await Promise.all([
          prisma.rentalHouse.findUnique({
            where: { id: rentalHouseOrder['houseId'] },
          }),
          prisma.sysUser.findUnique({
            where: { userId: userId },
          }),
          prisma.sysUser.findUnique({
            where: { userId: rentalHouseOrder['landlord'] },
          }),
        ]);
        if (!house) throw new Error('房屋不存在');
        if (!user) throw new Error('用户不存在');
        if(house.status==='0') throw new Error('当前房屋已被租赁');
        if(house.delFlag==='0') throw new Error('当前房屋已下架');
        const price = house.price.add(house.deposit);
        if (price.gt(user.money)) throw new Error('余额不足');
        await prisma.sysUser.update({
          where: { userId: userId },
          data: { money: user.money.sub(price) },
        });
        await prisma.sysUser.update({
          where: { userId: landlord.userId },
          data: { money: landlord.money.add(price) },
        });
        const leaseData = {
          tenantId: userId,
          houseId: rentalHouseOrder['houseId'],
          startDate: rentalHouseOrder['startDate'],
          endDate: rentalHouseOrder['endDate'],
          leaseStatus: '0',
          delFlag: '1',
        };
        const lease = await prisma.rentalLease.upsert({
          where: {
            tenantId_houseId: {
              tenantId: userId,
              houseId: rentalHouseOrder['houseId'],
            },
          },
          update: leaseData,
          create: leaseData,
        });
        await prisma.rentalHouse.update({
          where: { id: rentalHouseOrder['houseId'] },
          data: { status: '0' },
        });
        await prisma.rentalPayment.create({
          data: {
            leaseId: lease.id,
            paymentType: '0', // 支付类型
            status: '1', // 支付状态
            paymentDate: nowDateTime(), // 当前时间
            amount: price,
            delFlag: '1',
            key: uuidv4().replace('-', '').slice(0, 9),
          },
        });
        return { message: `购买成功 支付金额为 ${price} 元`, code: 200 };
      })
      .catch((err) => ({ message: err.message || '操作失败', code: 500 }));
  }

  /**@description 查询房源表所有 */
  async selectHouseAll() {
    const data = await this.prisma.rentalHouse.findMany({
      include: {
        image: { where: { delFlag: '1' }, select: { imageUrl: true } },
      },
    });
    return data.map((v) => ({ ...v, image: v.image.imageUrl }));
  }

  /**@description 分页查询房源表列表 */
  async selectHouseList(q: QueryRentalHouseDto) {
    let queryCondition: Prisma.RentalHouseWhereInput = {};
    if (isNotEmpty(q['title'])) {
      queryCondition.title = {
        contains: q.title,
      };
    }
    if (isNotEmpty(q['ownerId'])) {
      queryCondition.ownerId = {
        equals: q.ownerId,
      };
    }
    if (isNotEmpty(q['price'])) {
      queryCondition.price = {
        equals: q.price,
      };
    }
    if (isNotEmpty(q['deposit'])) {
      queryCondition.deposit = {
        equals: q.deposit,
      };
    }
    if (isNotEmpty(q['status'])) {
      queryCondition.status = {
        equals: q.status,
      };
    }
    if (isNotEmpty(q['delFlag'])) {
      queryCondition.delFlag = {
        equals: q.delFlag,
      };
    }
    if (
      isNotEmpty(q.params.beginUpdateTime) &&
      isNotEmpty(q.params.endUpdateTime)
    ) {
      queryCondition.updateTime = {
        lte: q.params.endUpdateTime,
        gte: q.params.beginUpdateTime,
      };
    }
    const rows = (
      await this.prisma.rentalHouse.findMany({
        skip: (q.pageNum - 1) * q.pageSize,
        take: q.pageSize,
        where: queryCondition,
        include: {
          image: {
            where: {
              delFlag: '1',
            },
            select: {
              imageUrl: true,
            },
          },
          owner: true,
        },
      })
    ).map((v) => ({ ...v, image: v.image.imageUrl }));
    const total = await this.prisma.rentalHouse.count({
      where: queryCondition,
    });
    return {
      rows,
      total,
    };
  }

  /**@description 查询房源表详情 */
  async selectHouseById(id: number) {
    const data = await this.prisma.rentalHouse.findUnique({
      where: {
        id,
      },
      include: {
        image: { where: { delFlag: '1' }, select: { imageUrl: true } },
        owner: true,
      },
    });
    return [data].map((v) => ({ ...v, image: v.image.imageUrl }))[0];
  }

  /**@description 新增房源表 */
  async addHouse(rentalHouse: CreateRentalHouseDto, ownerId: number) {
    if (isEmpty(rentalHouse['title'])) {
      delete rentalHouse['title'];
    }
    if (isEmpty(rentalHouse['ownerId'])) {
      delete rentalHouse['ownerId'];
    }
    if (isEmpty(rentalHouse['price'])) {
      delete rentalHouse['price'];
    }
    if (isEmpty(rentalHouse['deposit'])) {
      delete rentalHouse['deposit'];
    }
    if (isEmpty(rentalHouse['status'])) {
      delete rentalHouse['status'];
    }
    if (isEmpty(rentalHouse['delFlag'])) {
      delete rentalHouse['delFlag'];
    }
    if (isEmpty(rentalHouse['updateTime'])) {
      delete rentalHouse['updateTime'];
    }
    if (isEmpty(rentalHouse['createTime'])) {
      delete rentalHouse['createTime'];
    }
    if (isEmpty(rentalHouse['address'])) {
      delete rentalHouse['address'];
    }
    if (isEmpty(rentalHouse['description'])) {
      delete rentalHouse['description'];
    }
    return this.prisma.$transaction(async (prisma) => {
      const { image, ...houseData } = rentalHouse;
      const house = await prisma.rentalHouse.create({
        data: { ...houseData, ownerId }, // 插入房屋信息
      });
      await prisma.rentalHouseImage.create({
        data: {
          houseId: house.id,
          imageUrl: image,
        },
      });
      return house;
    });
  }

  /**@description 修改房源表 */
  async updateHouse(rentalHouse: UpdateRentalHouseDto) {
    if (isEmpty(rentalHouse['title'])) {
      delete rentalHouse['title'];
    }
    if (isEmpty(rentalHouse['ownerId'])) {
      delete rentalHouse['ownerId'];
    }
    if (isEmpty(rentalHouse['price'])) {
      delete rentalHouse['price'];
    }
    if (isEmpty(rentalHouse['deposit'])) {
      delete rentalHouse['deposit'];
    }
    if (isEmpty(rentalHouse['status'])) {
      delete rentalHouse['status'];
    }
    if (isEmpty(rentalHouse['delFlag'])) {
      delete rentalHouse['delFlag'];
    }
    if (isEmpty(rentalHouse['updateTime'])) {
      delete rentalHouse['updateTime'];
    }
    if (isEmpty(rentalHouse['createTime'])) {
      delete rentalHouse['createTime'];
    }
    if (isEmpty(rentalHouse['address'])) {
      delete rentalHouse['address'];
    }
    if (isEmpty(rentalHouse['description'])) {
      delete rentalHouse['description'];
    }

    return this.prisma.$transaction(async (prisma) => {
      const { image, ...houseData } = rentalHouse;
      const house = await prisma.rentalHouse.update({
        where: {
          id: rentalHouse.id,
        },
        data: houseData,
      });
      await prisma.rentalHouseImage.update({
        where: {
          houseId: rentalHouse.id,
        },
        data: { imageUrl: image },
      });
      return house;
    });
  }

  /**@description 批量删除房源表 */
  async deleteHouseByIds(ids: number[]) {
    return this.prisma.$transaction(async (prisma) => {
      await prisma.rentalHouseImage.deleteMany({
        where: {
          houseId: {
            in: ids,
          },
          house: { status: '1' }
        },
      });
      return prisma.rentalHouse.deleteMany({
        where: {
          id: {
            in: ids,
          },
          status: '1'
        },
      });
    });
  }

  /**@description 单个删除房源表 */
  async deleteHouseById(id: number) {
    return this.prisma.$transaction(async (prisma) => {
      await prisma.rentalHouseImage.delete({
        where: { houseId: id, house: { status: '1' } },
      });
      return prisma.rentalHouse.delete({
        where: { id, status: '1' },
      });
    });
  }

  /**@description 导出房源表所有数据为xlsx */
  async exportHouse(res: Response) {
    let title = [
      '房源ID',
      '房源标题',
      '房东ID',
      '租金',
      '押金',
      '出售状态（0-已租，1-空置）',
      '房源标记（0-已删除，1-正常）',
      '更新时间',
      '创建时间',
      '房源地址',
      '房源描述',
    ];
    let data = (await this.prisma.rentalHouse.findMany()).map((v) =>
      Object.values(v),
    );
    data.unshift(title);
    await exportTable(data, res);
  }
}
